
//
// 101125a- AH - Created.
// 101125b- AH - Updates tree when resources has been removed or deleted by
//               listening to change events.
// 101127 - AH - Generate HistoricalEvent when resource "Wall" is opened from
//               here.
// 110120 - AH - (Garage *) Minor code format fixes. 
// 110423 - AH - No more direct access to ontology on SoekratEngine, must
//               use getWheel() first to get.
// 110615a- AH - (Bybanen *) Made tree editable and registered 
//               ResourceTreeCellEditor.
// 110615b- AH - (Bien *) Removed button to show wall in dialog.
// 110617a- AH - createResource().
// 110617b- AH - getSelectedResource() and getSelectedTag().
// 110617c- AH - createTag(Resource).
// 110617d- AH - removeResource(Resource).
// 110617e- AH - removeTag(Resource, SoekratName).
//

package org.soekrat.gui.swing.resource;

import java.awt.BorderLayout;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import org.soekrat.engine.Soekrat2Engine;
import org.soekrat.engine.SoekratName;
import org.soekrat.engine.event.SoekratChangeEvent;
import org.soekrat.engine.event.SoekratChangeListener;
import org.soekrat.engine.mine.Mine;
import org.soekrat.engine.mine.Resource;

/**
 * <p>
 *   Table view of the
 *   {@link Mine}.
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC) 
 */
@SuppressWarnings("serial")
public final class ResourceTreePanel extends JPanel 
{
  private ResourceTreeModel m_model=ResourceTreeModel.EMPTY_MODEL;  

  private final JTree m_tree=new JTree(m_model);
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param engine Engine interfaced.
   */
  public ResourceTreePanel(Soekrat2Engine engine) 
  {
    if (engine==null)
    {
      throw new NullPointerException("engine");
    }
    
    setLayout(new BorderLayout());
    
    add(new JLabel("Mine Fan", JLabel.CENTER), BorderLayout.NORTH);
    
    final Mine mine=engine.getWheel().getMine();
    mine.addChangeListener
    (
      new SoekratChangeListener()
      {  
        public void changed(SoekratChangeEvent e) 
        {
          m_model=new ResourceTreeModel(mine);          
          m_tree.setModel(m_model);
        }
      }
    );
    
    m_tree.getSelectionModel().setSelectionMode(
      TreeSelectionModel.SINGLE_TREE_SELECTION);
    m_tree.setEditable(true);
    m_tree.setCellEditor(new ResourceTreeCellEditor(m_tree));
    m_tree.setCellRenderer(ResourceTreeCellRenderer.INSTANCE);
    m_tree.setRootVisible(false);
    
    m_model=new ResourceTreeModel(mine);
    m_tree.setModel(m_model);
    
    add(new JScrollPane(m_tree), BorderLayout.CENTER);
  }
  
  /**
   * <p>
   *   Gets selected
   *   {@link Resource}.
   * </p>
   * @return Selected or {@code null} if none selected.
   */
  public Resource getSelectedResource()
  {
    TreePath tp=m_tree.getSelectionPath();
    int n=(tp==null) ? 0 : tp.getPathCount();
    switch (n)
    {
      case 2  : return (Resource)tp.getLastPathComponent();
      case 3  : return (Resource)tp.getParentPath().getLastPathComponent();
      default : return null;
    }  
  }
  
  /**
   * <p>
   *   Gets selected tag.
   * </p>
   * @return Selected or {@code null} if none selected.
   */
  public SoekratName getSelectedTag()
  {
    TreePath tp=m_tree.getSelectionPath();
    int n=(tp==null) ? 0 : tp.getPathCount();
    switch (n)
    {
      case 3  : return (SoekratName)tp.getLastPathComponent();
      default : return null;
    }  
  }
  
  /**
   * <p>
   *   Creates a 
   *   {@link Resource} with initial name.
   * </p>
   * @return Created.
   */
  public Resource createResource(){ return m_model.createResource(); }
  
  /**
   * <p>
   *   Creates tag with initial name.
   * </p>
   * @param r {@link Resource} to create tag for.
   * @return Created.
   * @throws IllegalArgumentException If {@code r} is not in viewed
   *         {@link Mine}.
   */
  public SoekratName createTag(Resource r)
  {
    if (r==null)
    {
      throw new NullPointerException("r");
    }
    
    return m_model.createTag(r);
  }
  
  /**
   * <p>
   *   Removes resource.
   * </p>
   * @param r Resource to remove.
   * @throws IllegalArgumentException If {@code r} is not in viewed
   *         {@link Mine}. 
   */
  public void removeResource(Resource r)
  {
    if (r==null)
    {
      throw new NullPointerException("r");
    }
    
    m_model.removeResource(r);
  }
  
  /**
   * <p>
   *   Removes tag.
   * </p>
   * @param r   {@link Resource} to remove tag of.
   * @param tag Tag to remove.
   * @throws IllegalArgumentException If {@code r} is not in viewed
   *         {@link Mine}.
   * @throws IllegalArgumentException If {@code tag} is not a tag of {@code r}.
   */
  public void removeTag(Resource r, SoekratName tag)
  {
    if (r==null)
    {
      throw new NullPointerException("r");
    }
    if (tag==null)
    {
      throw new NullPointerException("tag");
    }
    
    m_model.removeTag(r, tag);
  }
  
}
